//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package project_issue_api_serv

import (
	"context"
	"time"

	"atomgit.com/openlinksaas/api-server/api_common"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/issue_dao"
	"atomgit.com/openlinksaas/api-server/utils"
	"atomgit.com/openlinksaas/proto-gen-go.git/notices/notices_issue"
	"atomgit.com/openlinksaas/proto-gen-go.git/project_issue_api"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *ProjectIssueApiImpl) SetStartTime(ctx context.Context, req *project_issue_api.SetStartTimeRequest) (*project_issue_api.SetStartTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.SetStartTimeResponse{
			Code:   project_issue_api.SetStartTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.SetStartTimeResponse{
			Code:   project_issue_api.SetStartTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.SetStartTimeResponse{
			Code:   project_issue_api.SetStartTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.SetStartTimeResponse{
			Code:   project_issue_api.SetStartTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.SetStartTimeResponse{
			Code:   project_issue_api.SetStartTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if issueItem.HasStartTime && issueItem.StartTime == req.StartTime {
		return &project_issue_api.SetStartTimeResponse{
			Code: project_issue_api.SetStartTimeResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := issue_dao.IssueDao.SetStartTime(sessCtx, req.ProjectId, req.IssueId, req.StartTime, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.SetStartTimeResponse{
			Code: project_issue_api.SetStartTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addSetStartTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.SetStartTimeResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) SetEndTime(ctx context.Context, req *project_issue_api.SetEndTimeRequest) (*project_issue_api.SetEndTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.SetEndTimeResponse{
			Code:   project_issue_api.SetEndTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.SetEndTimeResponse{
			Code:   project_issue_api.SetEndTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.SetEndTimeResponse{
			Code:   project_issue_api.SetEndTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.SetEndTimeResponse{
			Code:   project_issue_api.SetEndTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.SetEndTimeResponse{
			Code:   project_issue_api.SetEndTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if issueItem.HasEndTime && issueItem.EndTime == req.EndTime {
		return &project_issue_api.SetEndTimeResponse{
			Code: project_issue_api.SetEndTimeResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := issue_dao.IssueDao.SetEndTime(sessCtx, req.ProjectId, req.IssueId, req.EndTime, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.SetEndTimeResponse{
			Code: project_issue_api.SetEndTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addSetEndTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.SetEndTimeResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) SetEstimateMinutes(ctx context.Context, req *project_issue_api.SetEstimateMinutesRequest) (*project_issue_api.SetEstimateMinutesResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code:   project_issue_api.SetEstimateMinutesResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code:   project_issue_api.SetEstimateMinutesResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code:   project_issue_api.SetEstimateMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code:   project_issue_api.SetEstimateMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code:   project_issue_api.SetEstimateMinutesResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if issueItem.HasEstimateMinutes && issueItem.EstimateMinutes == uint32(req.EstimateMinutes) {
		return &project_issue_api.SetEstimateMinutesResponse{
			Code: project_issue_api.SetEstimateMinutesResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := issue_dao.IssueDao.SetEstimateMinutes(sessCtx, req.ProjectId, req.IssueId, req.EstimateMinutes, nowTime)
		if err != nil {
			return nil, err
		}

		return &project_issue_api.SetEstimateMinutesResponse{
			Code: project_issue_api.SetEstimateMinutesResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addSetEstimateMinutesEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.SetEstimateMinutesResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) SetRemainMinutes(ctx context.Context, req *project_issue_api.SetRemainMinutesRequest) (*project_issue_api.SetRemainMinutesResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.SetRemainMinutesResponse{
			Code:   project_issue_api.SetRemainMinutesResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.SetRemainMinutesResponse{
			Code:   project_issue_api.SetRemainMinutesResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.SetRemainMinutesResponse{
			Code:   project_issue_api.SetRemainMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.SetRemainMinutesResponse{
			Code:   project_issue_api.SetRemainMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.SetRemainMinutesResponse{
			Code:   project_issue_api.SetRemainMinutesResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := issue_dao.IssueDao.SetRemainMinutes(sessCtx, req.ProjectId, req.IssueId, req.RemainMinutes, nowTime)
		if err != nil {
			return nil, err
		}

		return &project_issue_api.SetRemainMinutesResponse{
			Code: project_issue_api.SetRemainMinutesResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addSetRemainMinutesEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.SetRemainMinutesResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) CancelStartTime(ctx context.Context, req *project_issue_api.CancelStartTimeRequest) (*project_issue_api.CancelStartTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.CancelStartTimeResponse{
			Code:   project_issue_api.CancelStartTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.CancelStartTimeResponse{
			Code:   project_issue_api.CancelStartTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.CancelStartTimeResponse{
			Code:   project_issue_api.CancelStartTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.CancelStartTimeResponse{
			Code:   project_issue_api.CancelStartTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.CancelStartTimeResponse{
			Code:   project_issue_api.CancelStartTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !issueItem.HasStartTime {
		return &project_issue_api.CancelStartTimeResponse{
			Code: project_issue_api.CancelStartTimeResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.UnsetStartTime(sessCtx, req.ProjectId, req.IssueId, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.CancelStartTimeResponse{
			Code: project_issue_api.CancelStartTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addCancelStartTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.CancelStartTimeResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) CancelEndTime(ctx context.Context, req *project_issue_api.CancelEndTimeRequest) (*project_issue_api.CancelEndTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.CancelEndTimeResponse{
			Code:   project_issue_api.CancelEndTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.CancelEndTimeResponse{
			Code:   project_issue_api.CancelEndTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.CancelEndTimeResponse{
			Code:   project_issue_api.CancelEndTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.CancelEndTimeResponse{
			Code:   project_issue_api.CancelEndTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.CancelEndTimeResponse{
			Code:   project_issue_api.CancelEndTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !issueItem.HasEndTime {
		return &project_issue_api.CancelEndTimeResponse{
			Code: project_issue_api.CancelEndTimeResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.UnsetEndTime(sessCtx, req.ProjectId, req.IssueId, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.CancelEndTimeResponse{
			Code: project_issue_api.CancelEndTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addCancelEndTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.CancelEndTimeResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) CancelEstimateMinutes(ctx context.Context, req *project_issue_api.CancelEstimateMinutesRequest) (*project_issue_api.CancelEstimateMinutesResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code:   project_issue_api.CancelEstimateMinutesResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code:   project_issue_api.CancelEstimateMinutesResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code:   project_issue_api.CancelEstimateMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code:   project_issue_api.CancelEstimateMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code:   project_issue_api.CancelEstimateMinutesResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !issueItem.HasEstimateMinutes {
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code: project_issue_api.CancelEstimateMinutesResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.UnsetEstimateMinutes(sessCtx, req.ProjectId, req.IssueId, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.CancelEstimateMinutesResponse{
			Code: project_issue_api.CancelEstimateMinutesResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addCancelEstimateMinutesEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.CancelEstimateMinutesResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) CancelRemainMinutes(ctx context.Context, req *project_issue_api.CancelRemainMinutesRequest) (*project_issue_api.CancelRemainMinutesResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code:   project_issue_api.CancelRemainMinutesResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, _, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code:   project_issue_api.CancelRemainMinutesResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code:   project_issue_api.CancelRemainMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code:   project_issue_api.CancelRemainMinutesResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code:   project_issue_api.CancelRemainMinutesResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !issueItem.HasRemainMinutes {
		return &project_issue_api.CancelRemainMinutesResponse{
			Code: project_issue_api.CancelRemainMinutesResponse_CODE_OK,
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)
	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.UnsetRemainMinutes(sessCtx, req.ProjectId, req.IssueId, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.CancelRemainMinutesResponse{
			Code: project_issue_api.CancelRemainMinutesResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	go apiImpl.addCancelRemainMinutesEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	return ret.(*project_issue_api.CancelRemainMinutesResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) SetDeadLineTime(ctx context.Context, req *project_issue_api.SetDeadLineTimeRequest) (*project_issue_api.SetDeadLineTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, roleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !(sessionItem.UserId == projectItem.OwnerUserId || roleItem.BasicInfo.Admin) {
		return &project_issue_api.SetDeadLineTimeResponse{
			Code:   project_issue_api.SetDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.SetDeadLineTime(sessCtx, req.ProjectId, req.IssueId, req.DeadLineTime, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.SetDeadLineTimeResponse{
			Code: project_issue_api.SetDeadLineTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//记录事件
	go apiImpl.addSetDeadLineTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	go apiImpl.adjustDelayCheckTask(req.ProjectId, req.IssueId, issueItem.State, true, req.DeadLineTime)
	return ret.(*project_issue_api.SetDeadLineTimeResponse), nil
}

func (apiImpl *ProjectIssueApiImpl) CancelDeadLineTime(ctx context.Context, req *project_issue_api.CancelDeadLineTimeRequest) (*project_issue_api.CancelDeadLineTimeResponse, error) {
	sessionItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	projectItem, _, roleItem, err := utils.GetProjectMemberRole(ctx, req.ProjectId, sessionItem.UserId)
	if err == utils.ErrNoProject {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_NO_PROJECT,
			ErrMsg: "项目不存在",
		}, nil
	} else if err == utils.ErrNoRole {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	} else if err != nil {
		return nil, err
	}
	if projectItem.Closed {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	issueItem, err := issue_dao.IssueDao.Get(ctx, req.ProjectId, req.IssueId)
	if err != nil {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_NO_ISSUE,
			ErrMsg: "工单不存在",
		}, nil
	}
	if !(sessionItem.UserId == projectItem.OwnerUserId || roleItem.BasicInfo.Admin) {
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code:   project_issue_api.CancelDeadLineTimeResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	nowTime := time.Now().UnixNano() / 1e6
	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = issue_dao.IssueDao.UnsetDeadLineTime(sessCtx, req.ProjectId, req.IssueId, nowTime)
		if err != nil {
			return nil, err
		}
		return &project_issue_api.CancelDeadLineTimeResponse{
			Code: project_issue_api.CancelDeadLineTimeResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//记录事件
	go apiImpl.addCancelDeadLineTimeEvent(sessionItem, req, projectItem, issueItem)
	go api_common.SendNoticeToProjectScope(context.Background(), req.ProjectId, &notices_issue.UpdateIssueNotice{
		ProjectId: req.ProjectId,
		IssueId:   req.IssueId,
	})
	go apiImpl.adjustDelayCheckTask(req.ProjectId, req.IssueId, issueItem.State, false, 0)
	return ret.(*project_issue_api.CancelDeadLineTimeResponse), nil
}
